//////////////////////////////////////////////////////////////////////////////
//
// File Name:  conGuy.h
//
//
// Author:   GiTM.soccerist
// Date:     5/23/04
// System:   Linux
// Compiler: gcc 3.2
//
// Description:  This is the header file for the conGuy class.
//   This class manages and processes all the necessary actions
//   required to connect to bnet.  (accnt, pwd and auth challenges).
//   It also handles all the interface and packet communication to bnet
//   after the connect.
//
// Status:  Complete.
//

#ifndef CONGUY_H
#define CONGUY_H

// The subdirectory to store the logs in.
#define LOGFILE_BASE "logs/"

#include<iostream>
#include<string>
#include<fstream>
#include<list>
using namespace std;

#include "buff.h"
#include "types.h"
#include "../authGuy/authGuy.h"
#include "../event/event.h"


// Pre-declare the conGuy class so the compiler doesn't complain.
class conGuy;


// sendQueue class:
//    This class contains a list of strings that need to be sent out 
//    to the server.
class sendQueue {
 public:
  list<string> out;
  pthread_mutex_t mutex;
};

// sendRequests class:
//   This class contains information (lists) of stuff that another conGuy
//   requested be sent.  Read the comments below for more in depth info.

class sendRequests {
 public:
  // These are the lists containing info about sends that another conGuy
  //   is requesting.  They are popped off from front and attempted to be
  //   serviced.  If the send is successful, then the lists' info gets
  //   push_back-ed onto the group of lists below.  The reason for this is 
  //   because if the send fails, at least we haven't tainted the
  //   group of lists below that are awaiting return confirmation
  //   and info on the send.
  list<string> out;
  list<conGuy*> fromConGuy;
  list<string>  fromWho;

  // These are the lists of things that are waiting for bnet to return the
  //   result.  Once the result is returned and it matches something
  //   that we requested with the front 'waiting' string, we let the user
  //   that requested it on their conGuy know.
  list<string>  waiting;
  list<conGuy*> returnToConGuy;
  list<string>  returnToWho;
  
  // mutex for this whole class.
  pthread_mutex_t mutex;
};


// conGuy class:
//   Big class/object that handles the connection-based stuff.
//
class conGuy {
 public:
  conGuy();
  ~conGuy();  // Close socket if it's open.
  
  bool done;

  bool connectNow(string this_gateway);
  bool disconnectNow();

  bool isConnected();
  sendQueue* getSendQueue();
  sendRequests* getSendRequests();
  bool purgeQueues();  // Purge the sendQueue and the sendRequests.

  string getMainGateway();   // The gateway the database-using conGuy is on.
  string getGateway();       // The gateway THIS conGuy is connected to.

  event gimmeEvent();    // Returns an event object.
  bool say(string msg);  // Sends a message/command.

  int getSd();  // Returns the socket descriptor for use elsewhere.
  string homeChannel();  // Returns the desired homeChannel.
  string username();     // Returns the unique username.
  bool getHaveOps();
  bool setHaveOps(bool ops);
  time_t getStartTime();
 private:
  bool sendBuffOut();  // Send sendBuff out.
  bool read_config(string this_gateway);  // Reads the config for the 
                                          // specified gateway.
  bool connectToBnet();   // Connect.

  int readit(int socket, void*msg_data, unsigned int msg_len);
  int writeit(int socket, void*msg_data, unsigned int msg_len);

  // Buffers
  buff sendBuff;
  buff recvBuff;

  // Queue of string that need to be sent out to the server.
  sendQueue toSend;
  sendRequests requests;

  // Output connection log file.  (for debugging and status output).
  ofstream conlog;
  
  // Time connection is made.
  time_t startTime;
  
  // Flood protection stuff
  timeval lastSendTime;
  unsigned short lastSendSize;
  // These are adjustable parameters used in our flood control.
  long sleep_sec_req;  // Minimum required seconds to sleep
  long sleep_usec_req; // Minimum required microseconds to sleep.
  long sleep_usec_per_byte;  // Number of microseconds to sleep per byte
                             // when packet size is > 30 bytes.
  bool updateLastSendTime();
  bool sleepRequiredTime();  // Call this before every send.
                             // It does a sleep() or usleep() as required.
  
  
  // Variables read in from the config file and used in the connect.
  string bot_gateway;    // This is the gateway the actual bot will run on.
  string gateway;        // The gateway this conGuy is working for.
  string server;     // Server address to connect to.
  int port;
  string home_channel;
  string account;
  string unique_username;
  bool haveOps;  // This is set in bot.cc in switch case EID_USERFLAGS.

  int sd;  // Socket Descriptor.  (Important number ;))

  
  // Authorization Object.  He holds auth functions and vars.
  authGuy auth;

  bool handle_nonchat();     // Handle a pkt that's not SID_CHATEVENT
  bool trash_curr_packet();  // Throw away the current packet.


  // Here are the packet handling functions:
  // (s stands for send, r stands for recv, pkt stands for packet)
  // I have found it annoying enough at work looking at undocumented code that
  // shall never adhere to that low standard.

  // Recieive functions have a precondition of the recvBuff being already 
  //   stripped.
  bool s_pkt_protocol();
  bool s_pkt_SID_AUTH_INFO();
  bool s_pkt_SID_PING(u32 pingValue);
  bool s_pkt_SID_AUTH_CHECK();
  bool s_pkt_SID_LOGONRESPONSE();
  bool s_pkt_SID_UDPPINGRESPONSE();
  bool s_pkt_SID_ENTERCHAT();
  bool s_pkt_SID_GETCHANNELLIST();
  bool s_pkt_SID_CHATCOMMAND(string msg);
  bool s_pkt_SID_JOINCHANNEL(string channel);
  bool s_pkt_SID_LEAVECHAT();
  bool s_pkt_SID_NULL();


  bool r_pkt_SID_PING(u32 &pingValue);
  bool r_pkt_SID_AUTH_INFO();
  bool r_pkt_SID_AUTH_CHECK();
  bool r_pkt_SID_LOGONRESPONSE();
  bool r_pkt_SID_GETCHANNELLIST();
  bool r_pkt_SID_ENTERCHAT();
  bool r_pkt_SID_FLOODDETECTED();
  bool r_pkt_SID_MESSAGEBOX();

};





// Below are the battle.net packet ID's.
#define SID_NULL			0x00  
#define SID_CLIENTID			0x05  
#define SID_STARTVERSIONING		0x06  
#define SID_REPORTVERSION		0x07  
#define SID_GETADVLISTEX		0x09  
#define SID_ENTERCHAT			0x0A  
#define SID_GETCHANNELLIST		0x0B  
#define SID_JOINCHANNEL			0x0C  
#define SID_CHATCOMMAND			0x0E  
#define SID_CHATEVENT			0x0F  
#define SID_LEAVECHAT                   0x10
#define SID_FLOODDETECTED		0x13  
#define SID_UDPPINGRESPONSE		0x14  
#define SID_MESSAGEBOX			0x19  
#define SID_PING			0x25  
#define SID_READUSERDATA		0x26  
#define SID_WRITEUSERDATA		0x27  
#define SID_LOGONCHALLENGE		0x28  
#define SID_LOGONRESPONSE		0x29  
#define SID_CREATEACCOUNT		0x2A  
#define SID_CHANGEPASSWORD		0x31  
#define SID_LOGONRESPONSE2		0x3A  
#define SID_CREATEACCOUNT2		0x3D  
#define SID_LOGONREALMEX		0x3E  
#define SID_AUTH_INFO			0x50  
#define SID_AUTH_CHECK			0x51  
#define SID_FRIENDLIST			0x65  
#define SID_FRIENDUPDATE		0x66  
#define SID_FRIENDADDED			0x67  
#define SID_FRIENDREMOVED		0x68  
#define SID_FRIENDMOVED			0x69  
#define SID_FINDCLANCANDIDATES		0x70  
#define SID_INVITEMULTIPLEUSERS		0x71  
#define SID_DISBANDCLAN			0x73  
#define SID_CLANINFO			0x75  
#define SID_CLANREQUEST			0x77  
#define SID_CLANINVITE			0x79  
#define SID_CLANMOTD			0x7C  
#define SID_CLANMEMBERLIST		0x7D  
#define SID_CLANMEMBERUPDATE		0x7F  


// Below are the Battle.net/Starcraft UDP packet ID's.
#define PKT_SERVERPING			0x05  
#define PKT_KEEPALIVE			0x07  
#define PKT_CONNTEST2			0x09  


#define BROOD_WAR_PRODUCT_ID            0x53455850

#endif



// End of   conGuy.h
